package thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author SWJ
 * @create 2021-06-23 14:38
 * 用接口实现多线程
 */
public class Thread2v3 {
    public static void main(String[] args) {

        T2v3 tn = new T2v3();
//        Thread t1 = new Thread(tn);
//        Thread t2 = new Thread(tn);
//        Thread t3 = new Thread(tn);

//        t1.start();//调用run()方法
//        t2.start();
//        t3.start();
        /**线程池ExecutorService用于创建储存线程的池子，把新建/启动/关闭线程
         * 都交给池子
         * Executors:用于创建线程池的工具类
         * newFixedThreadPool(线程数)--创建一个指定的线程数的线程池
         * 9.创建线程池的对象，线程池容纳的线程数指定为5*/
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            pool.execute(tn);
            /**10.execute()让线程池中来还行*/
        }
    }
}

class T2v3 implements Runnable {
    static int tc1 = 100;
    /**
     * 实现接口的方式，不限制锁对象的类型，只需要保持锁对象的唯一
     * 也就是提取到成员位置创建对象即可
     */
    Object o = new Object();
    //注意这里要加静态 不然会一直调用

    @Override
    public void run() {
        //添加未实现的方法，将业务在run()中
        while (true) {
            //主动让线程休眠，出现阻塞状态
            // synchronized (new Object()) {
            /**一个方法中的所有的代码均需要同步
             * 那么可以用synchronized修饰方法为同步方法*/
            synchronized (o) {
                //定义锁对象必须唯一 此方法不正确
                //原因：每个线程执行run()时都会new一个对象
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //双重校验：加判断
                if (tc1 > 0) {
                    System.out.println(Thread.currentThread().getName() + "=" + tc1--);
                }
                if (tc1 <= 0) break;
                //设置出口
            }
        }

    }
}
